#ifndef EXPRESSION_H_
#define EXPRESSION_H_

#include <sstream>

class Expression
{
private:
	static bool isNumber(char c) { return (c > 47 && c < 58); }
	static bool isWhitespace(char c) { return (c == '\t' || c == ' '); }
	static bool isOperation(char c) { return (c == '+' || c == '-' || c == '*' || c == '/' || c == '^' || c == '|'); }

	template <class T>
	static bool parseValue(T& value, const char **input, 
		std::ios_base& (*f)(std::ios_base&))
	{
		std::istringstream iss(*input);
		bool success = !(iss >> f >> value).fail();
		if(success)
			(*input) += iss.tellg();
		return success;
	}

	static bool parseBinary(int &value, const char **input)
	{
		const char *p = *input;
		while(*p == '1' || *p == '0')
			p++;

		int binaryLength = p - *input;
		if(!binaryLength)
			return false;

		value = 0;
		for(; *input != p; (*input)++)
		{
			binaryLength--;
			if(**input == '1')
				value += pow(2.0f, static_cast<float>(binaryLength));
		}

		return true;
	}

	static Expression *parseSubexpression(const char **input);

	static Expression *parseInternal(const char *string, const char *orig);
	static Expression *parse2(const char *string, int len);
public:
	static Expression *parse(const char *string);
	
	virtual float value() = 0;
	virtual void printInfix() = 0;
	virtual void printRpn() = 0;

	virtual ~Expression() {}
};

#endif